<?php
/**
 * Класс предназначен для работы с сессиями
 *
 */
class User_Session {
  private $ascii_session_id;          //Сгенерированный PHP идентификатор сеанса (32 символа)
  private $ID_user_session;       //Идентификатор сеанса, используемый в базе данных (нужен для связи сущностей в базе данных)
  private $logged_in;               //[bool] Логическая переменная, определяющая активность сеанса
  private $ID_user;                 //Идентификатор (берется из БД) текущего зарегистрированного пользователя
  private $sessionTimeout = 60000000;   //Время ожидания. Если период между запросами превышает эту величину, сеанс прерывается.
  private $sessionLifespan = 36000000; //Максимальный срок действия сеанса
  private $superSlovo = 'superSlovo';
  private $objUser;

  /**
   * Конструктор. Переопределяет ф-ции для работы с сессией
   *
   */
  private function __construct() {
    session_set_save_handler(
      array(&$this, '_session_open_method'),
      array(&$this, '_session_close_method'),
      array(&$this, '_session_read_method'),
      array(&$this, '_session_write_method'),
      array(&$this, '_session_destroy_method'),
      array(&$this, '_session_gc_method')
    );
    //Проверка cookie: переданы ли эти данные и корректны ли они
    $struser_agent = (isset($_SERVER['HTTP_USER_AGENT'])) ? $_SERVER['HTTP_USER_AGENT'] : '';

    if (isset($_COOKIE["PHPSESSID"]) && $_COOKIE["PHPSESSID"]) {
      // Проверка сроков давности для безопасности
      $this->ascii_session_id = $_COOKIE["PHPSESSID"];//Идентификатор сеанса

      $arResult = $this->_baseGetCorrectSessionsWithAscii();
      if (sizeof($arResult) == 0) { // Если в базе нет такого идентификатора сесии или срок действия сеанса истек или используется другой пользовательский агент или ( с последнего обращения к странице прошло больше времени, чем время ожидания или не было обращений к странице)
        $failed = 1; // Установка флага failed
        // Удаление из базы данных - периодическая сборка мусора
        // Удаляем сессию с соответствующим ascii_session_id и сессии, у которых истек максимальный срок действия сеанаса
        //$this->_baseDeleteIncorrectSessionsAndAsciiSess();
        // Очищаем переменные сеанса
        // Удаляем все переменные сесии, для которых не осталось соответствующей сессии
        //$this->_baseDeleteIncorrectSessionsVariables();
        unset($_COOKIE["PHPSESSID"]); // Удаление идентификатора в cookie
      }
    }
    session_set_cookie_params($this->sessionLifespan); // Установка времени жизни данных cookie
    session_start();//Вызовется сначала _session_open,  потом _session_read
  }

  /**
   * Функция обеспечивает работу шаблона Singleton
   * Благодаря ей у нас всегда будет только один объект пользовательской сессии
   *
   * @return object - объект сессии
   */
  static public function instance() {
    static $objSession;
    if (!isset($objSession)) {
      $objSession = new User_Session();
    }
    return $objSession;
  }

  /**
   * Позволяет определить факт нового обращения к странице
   * Должен вызываться на любой странице в которой используется класс сеанса,
   * сразу же после его инстанцирования
   *
   */
  public function impress() {
    if ($this->ID_user_session) {//Если имеется идентификатор сеанса, используемый в базе, то
    	if ($this->isLoggedIn()) {
    		$lastImpression = $this->_baseGetLastImpression();

    		/*if ( time() - strtotime($lastImpression) > 900) {
      		User_User::setLoginTime();
    			User_User::addVisit();
      		User_User::setStatus(2, $this->getUserId());
      	}*/
      }
    	$this->_baseUpdatelast_impression();//Обновляем время последнего обращения

      User_User::addHit();
    }
  }

  /**
   * Проверка регистрации пользователя в рамках сеанса
   *
   * @return bool - залогинен или нет
   */
  public function isLoggedIn() {
    return($this->logged_in);
  }

  /**
   * Получение идентификатора пользователя
   *
   * @return int - ID пользователя
   */
  public function getUserId() {
    if ($this->logged_in) {//Если сеанс активен
      return($this->ID_user);
    }
    else {
      return false;
    };
  }


  /**
   * Получение объекта пользователя
   *
   * @return object - объект пользователя
   */
  public function getUser() {
    if (!isset($this->objUser)) {
      if ($this->logged_in) $this->objUser =  new User_User($this->getUserId());
      else $this->objUser =  new User_User();
    }
    return $this->objUser;
  }

  /**
   * Получение идентификатора сессии
   *
   * @return int - ID пользователя
   */
  public function getUserSessionId() {
      return $this->ID_user_session;
  }

  /**
   * Возвращает 32-символьный идентификатор сеанса PHP
   *
   * @return string - 32-символьный идентификатор сеанса PHP
   */
  public function getSessionIdentifier() {
    return($this->ascii_session_id);
  }

  /**
   * Функция входа
   * Получает логин и пароль
   * Возвращает true, если удалось залогиниться
   *
   * @param string $strUsername - Имя пользователя
   * @param string $strPlainPassword - Пароль
   * @param string $Save - Запомнить меня
   * @return bool - Залогинились или нет
   */
  public function logIn($loginOrEMail, $strmd5Pass, $no_save = false) {
  	$ID_user = User_User::logIn($loginOrEMail, $strmd5Pass);
    if ($ID_user) {//Если есть совпадения (логин+пароль)
      $this->ID_user = $ID_user;//Запоминаем id пользователя
      $this->logged_in = true;//Активируем сеанс
      //Обновляем БД
      //Устанавливаем статус активного сеанса, запоминаем id пользователя для текущ0его сеанса
      $this->_baseLogInSession();
      User_User::setLoginTime();
      User_User::addVisit();
      User_User::setStatus(2, $this->getUserId());
      if ($no_save) {
      	$objUser = self::getUser();
				$superStr = md5($objUser->getField('e_mail') . $this->superSlovo . $strmd5Pass . $this->superSlovo);
				setcookie("SaveMe" , $superStr , time() + 60480000, W_ABSPATH);
				setcookie("ID" , $ID_user , time() + 60480000, W_ABSPATH);
			}
      return true;
    }
    else { // Если НЕТ совпадений (логин+пароль)
			return false;
    };
  }

  /**
   * Функция автозахода если пользователь ставил галочку "Запомнить меня"
   *
   * @return bool - Запомнили или нет
   */
  public function ifSaveMe() {
  	if ($this->logged_in == false) { //Если сеанс не активен
  		if (isset($_COOKIE['SaveMe']) && isset($_COOKIE['ID'])) { //Если в куках храняться значения ИД и хэш SaveMe
  			$objDB = Service_Database::instance();
  			//Делаем выборку майла и пароля по ИД
  			$strUserAndPass = 'SELECT `e_mail`, `login`, `pass` FROM `user` WHERE ID_user="' . $_COOKIE['ID'] . '"';
  			$arUserAndPass = $objDB->select($strUserAndPass);
  			if ($arUserAndPass) { //Если есть совпадение
  				$mail = $arUserAndPass[0]['e_mail'];
  				$md5pass = $arUserAndPass[0]['pass'];
  				$superStr = md5($mail . $this->superSlovo . $md5pass . $this->superSlovo); //Формируем супер строку =)
  				if ($superStr == $_COOKIE['SaveMe']) { //Если супер строка равна хэшу в куках
  					//Заново логинимся, все довольны =)
  					$ID_user = User_User::logIn($arUserAndPass[0]['login'], $md5pass);
  					if ($ID_user) {//Если есть совпадения (логин+пароль)
  						$this->ID_user = $ID_user;//Запоминаем id пользователя
  						$this->logged_in = true;//Активируем сеанс
  						//Обновляем БД
  						//Устанавливаем статус активного сеанса, запоминаем id пользователя для текущ0его сеанса
  						$this->_baseLogInSession();
  						User_User::setLoginTime();
  						User_User::addVisit();
  						User_User::setStatus(2, $this->getUserId());
  						return true;
  					}
  					else { // Если НЕТ совпадений (логин+пароль)
  						return false;
  					}
  				}
  			}
  		}
  	}
  }

  /**
   * Функция автозахода если пользователь ставил галочку "Запомнить меня"
   *
   * @return bool - Запомнили или нет
   */
  public function facebookLogin($email) {
  	if ($this->logged_in == false) { //Если сеанс не активен
			$objDB = Service_Database::instance();
			//Делаем выборку майла и пароля по ИД
			$strUserAndPass = 'SELECT `e_mail`, `login`, `pass`, `approved` FROM `user` WHERE e_mail="' . $email . '"';
			$arUserAndPass = $objDB->select($strUserAndPass);
			if (isset($arUserAndPass[0])) { //Если есть совпадение
				if (!$arUserAndPass[0]['approved']) {
					$stmt = 'UPDATE `user` SET `approved` = 1 WHERE e_mail="' . $email . '"';
					$objDB->query($strUserAndPass);
				}
				//Заново логинимся, все довольны =)
				$ID_user = User_User::logIn($arUserAndPass[0]['login'], $arUserAndPass[0]['pass']);
				if ($ID_user) {//Если есть совпадения (логин+пароль)
					$this->ID_user = $ID_user;//Запоминаем id пользователя
					$this->logged_in = true;//Активируем сеанс
					//Обновляем БД
					//Устанавливаем статус активного сеанса, запоминаем id пользователя для текущ0его сеанса
					$this->_baseLogInSession();
					User_User::setLoginTime();
					User_User::addVisit();
					User_User::setStatus(2, $this->getUserId());
					return true;
				}
				else { // Если НЕТ совпадений (логин+пароль)
					return false;
				}
			}
		}
  }

  /**
   * Функция выхода
   * Возвращает true, если вышли. false, если сеанс не был активен
   *
   * @return bool - Вышли или нет
   */
  public function logOut() {
    if ($this->logged_in) {//Если сеанс активен
      //Устанавливаем для текущей сессии состоянии НЕ активный сеанс и обнуляем пользователя.
      User_User::setStatus(0, $this->getUserId());
      $this->_baseLogOutSession();
      $this->logged_in = false; //Деактивируем сеанс
      $this->ID_user = 0; //Обнуляем id пользователя
      setcookie("SaveMe", null, null, W_ABSPATH);
      return true;
    }
    else { // Если сеанс НЕ активен
      return false;
    }
  }


  /**
   * Метод переправляет пользователя на другую страницу. При необходимости сохраняет сообщение в переменную сессиии
   *
   * @param string $location
   * @param string $message
   * @param integer $messageType
   */
  public static function moveTo($location, $message = null, $messageType = -1, $saveHtml = false) {
    if ($message)
      if ($messageType > 0) User_Flash::_set('successMessage', $message, $saveHtml);
      else {
        //$exitPageFlag = User_Flash::_get('exit_page');
        //if (!isset($_SERVER['HTTP_REFERER']))  User_Flash::_set('errorMessage', $message);
          //echo $_SERVER['HTTP_REFERER'];
          //if (strpos($_SERVER['HTTP_REFERER'], '/auth/exit/') === false)
          /*if ($exitPageFlag != 1) */ User_Flash::_set('errorMessage', $message);

      }
    //Pressure::saveDuration(getCurrentUrl(), 2, Pressure::calculateCurrentDuration());
    //User_Flash::__delete('exit_page');
    header('HTTP/1.1 301 Moved Permanently');
    header('Location: ' . $location);
    exit();
  }

  /**
   * Метод переправляет пользователя на другую страницу. В том, случае, если пользователь не зарегистрирован
   * В противном случае возвращает идентификатор пользователя
   *
   * @param string $location
   * @param string $message
   * @param integer $messageType
   */
  public static function moveToIfNotRegist($location, $message = null) {
    $objSession = self::instance();
    $userId = $objSession->getUserId();
    if (!$userId)
      $objSession->moveTo($location, $message);
    return $userId;
  }

/**
 * Эта функция запускается при открытии сессии - сделана на будущее для дополнительных возможных проверок и пр.
 * Получает путь $save_path, по которому должны храниться переменные сеанса и имя файла cookie
 *
 * @param atring $save_path
 * @param string $session_name
 * @return bool
 */
  private function _session_open_method($save_path, $session_name) {
    //Ничего не делаем
    return true;
  }

  /**
   * Эта функция запускается при закрытии сессии
   *
   * @return bool
   */
  public function _session_close_method() {
    //Ничего не делаем
    return true;
  }

  /**
   * Эта функция используется при попытке извлечения переменной из массива $_SESSION
   * Ей передается идентификатор сеанса
   * По умолчанию возвращает сериализованное представление массива $_SESSION, но не в нашем случае, т.к. у нас собственная обработка
   *
   * @param integer $id - ID сеанса
   * @return string - Пустая строка
   */
  private function _session_read_method($id) {
    //Используется для проверки существования сеанса
    $struser_agent = (isset($_SERVER['HTTP_USER_AGENT'])) ? $_SERVER['HTTP_USER_AGENT'] : '';
    $this->ascii_session_id = $id; //Записываем id сессии
    $failed = 1; //Установка флага failed
    //Проверить наличие данных в базе данных
    //(Есть ли соответствующая текущему id сессия?)
    $arResult = $this->_baseGetSessionById($id);
    if (sizeof($arResult) > 0) { //Если сессия с текущим id существует, то...
      $this->ID_user_session = $arResult[0]["ID_user_session"]; //Запоминаем id сессии из БД
      if ($arResult[0]["logged_in"]==1) { //Если сеанс активен
        $this->logged_in = true; //Активируем сеанс
        $this->ID_user = $arResult[0]["ID_user"]; //Записываем id пользователя
      }
      else { //Если сеанс НЕ активен
        $this->logged_in = false; //Деактивируем сеанс
      }
    }
    else { //Если сессия с текущим id НЕ существует, то...
      $this->logged_in = false; //Деактивируем сеанс
      //Необходимо создать запись в БД
      //Сессия с текущим id, деактивированная, без соответствия пользователя...

      $this->ID_user_session = $this->_baseCreateNewEmptySessionByAscii($id, $struser_agent);
    }
    return(""); // Возвращаем пустую строку
  }

/**
 * Эта функция вызывается при попытке модифицировать массив $_SESSION
 * Ей передается идентификатор сеанса + сериализованное представление массива $_SESSION
 * Возвращает true, если все ок.
 * Вызывается даже если переменные сеанса не зарегистрированы, и при первом вызове записывает сгенерированный идентификатор сеанса
 *
 * @param integer $id - ID сеанса
 * @param string $sess_data - Сериализованное представление массива $_SESSION
 * @return bool
 */
  public function _session_write_method($id, $sess_data) {
    return true;
  }

  /**
   * Вызывается при вызове в коде функции session_destroy();
   *
   * @param integer $id - ID сеанса
   */
  private function _session_destroy_method($id) {
    $objDB = Service_Database::instance();
    $objDB->delete('session', array('ascii_session_id' => $id));
  }

  /**
   * Функция сборки мусора.
   * Получает максимальное время жизни данных cookie для текущего сеанса
   * Удаляет любые данные, срок жизни которых превышает заданный
   *
   * @param integer $maxlifetime - Время жизни сеанса
   * @return bool
   */
  private function _session_gc_method($maxlifetime) {
    return true;
  }

  /**
   * Функция работает с БД
   * Функция выбирает из БД все сессии с соответствующим ASCII сессии
   *
   * @return array - Массив с сессией
   */
  private function _baseGetCorrectSessionsWithAscii() {
    $objDB = Service_Database::instance();
    $stmt = "SELECT ID_user_session, logged_in FROM `session` WHERE ascii_session_id = '" . $this->ascii_session_id . "' AND ((now() - created) < ' " . $this->sessionLifespan . " seconds') AND user_agent='" . $_SERVER['HTTP_USER_AGENT'] . "' AND ((now() - last_impression) <= '" . $this->sessionTimeout . " seconds' OR last_impression IS NULL)";
    return $objDB->select($stmt);
  }

  /**
   * Функция работает с БД
   * Функция выбирает из БД сессию с соответствующим 32-симв идентификатором
   *
   * @param integer $id - ID сеанса
   * @return array - Массив с сессией
   */
  private function _baseGetSessionById($id) {
    $objDB = Service_Database::instance();
    $stmt = "SELECT ID_user_session, logged_in, ID_user FROM `session` WHERE ascii_session_id = '$id'";
    return $objDB->select($stmt);
  }

  /**
   * Функция работает с БД
   * Удаляет все сессии, у которых истекло время жизни и текущую сессию согласно ее 32симв. идентификатору
   *
   * @return bool - Удалено или нет
   */
  private function _baseDeleteIncorrectSessionsAndAsciiSess() {
    $objDB = Service_Database::instance();
    //$sql = "DELETE FROM `session` WHERE (ascii_session_id = '". $this->ascii_session_id . "') OR ((now() - created) > $this->sessionLifespan)";
    $sql = "DELETE FROM `session` WHERE (ascii_session_id = '". $this->ascii_session_id . "')";
    return $objDB->query($sql);
  }

  /**
   * Функция работает с БД
   * Удаляет все переменные сессий, которые ссылаются на уже удаленные сессии
   *
   */
  private function _baseDeleteIncorrectSessionsVariables() {
    $objDB = Service_Database::instance();
    $sql = "DELETE FROM `session_variable` WHERE ID_user_session NOT IN (SELECT ID_user_session FROM `session`)";
    $objDB->query($sql);
  }

  /**
   * Функция работает с БД
   * Обновляет время последней активности сессии
   *
   */
  private function _baseUpdatelast_impression() {
    $objDB = Service_Database::instance();
    $sql = "UPDATE `session` SET last_impression = now() WHERE ID_user_session = " . $this->ID_user_session;
    $objDB->query($sql);
  }

  /**
   * Функция работает с БД
   * Обновляет время последней активности сессии
   * @return mixed - Массив с пользователем
   */
  private function _baseGetLastImpression() {
    $objDB = Service_Database::instance();
    $sql = "SELECT `last_impression` FROM `session` WHERE `ID_user_session` = '" . $this->ID_user_session . "'";
    return $objDB->selectSimpleField($sql);
  }

  /**
   * Функция работает с БД
   * Проверяет, есть ли пользователь с соответствующими login+password
   *
   * @param string $strUsername - Имя пользователя
   * @param string $strMD5Password - Пароль в MD5
   * @return array - Массив с пользователем
   */
  private function _baseIsLogInCorrect($strUsername, $strMD5Password) {
    $objDB = Service_Database::instance();
    $stmt = "SELECT ID_user FROM `user` WHERE nick = '$strUsername' AND md5Pw = '$strMD5Password'";
    return $objDB->select($stmt);
  }

  /**
   * Функция работает с БД
   * Устанавливает необходимые поля у сессии в состояние "Не аутентифицировано"
   *
   */
  private function _baseLogOutSession() {
    $objDB = Service_Database::instance();
    //$objDB->query('UPDATE `session` SET `session`.`logged_in` = "false", `session`.`ID_user` = null WHERE `session`.`ID_user_session` = "' . $this->ID_user_session . '"');
    //$objDB->query('session', array('logged_in' => false, 'ID_user' => 'null'), array('ID_user_session' => $this->ID_user_session));
    $objDB->update('session', array('logged_in' => 0), array('ID_user_session' => $this->ID_user_session));
    //$this->moveTo(W_ABSPATH);
  }

  /**
   * Функция работает с БД
   * Устанавливает необходимые поля у сессии в состояние "Аутентифицировано"
   *
   */
  private function _baseLogInSession() {
    $objDB = Service_Database::instance();
    $objDB->update('session', array('logged_in' => true, 'ID_user' => $this->ID_user), array('ID_user_session' => $this->ID_user_session));
  }

  /**
   * Функция работает с БД
   * Устанавливает необходимые поля у сессии в состояние "Аутентифицировано"
   *
   * @param string $idAscii - 32-символьный идентификатор сеанса
   * @param string $struser_agent - Агент пользователя
   * @return integer - ID сеанса
   */
  private function _baseCreateNewEmptySessionByAscii($idAscii, $struser_agent) {
    $objDB = Service_Database::instance();
    $objDB->query("INSERT INTO `session` (ascii_session_id, logged_in, ID_user, created, user_agent) VALUES ('$idAscii','0', null, now(),'$struser_agent')");
    //Получение истинного идентификатора от только что вставленных данных
    $arResult = $objDB->select("SELECT ID_user_session FROM `session` WHERE ascii_session_id = '$idAscii'");
    return $arResult[0]["ID_user_session"];
  }

  /**
   * Запись значения переменной $nm, относящееся к текущей сессии
   *
   * @param string $nm - Имя параметра
   * @param string $val - Значение параметра
   */
  public function __set($nm, $val) {
    $objDB = Service_Database::instance();
    $strSer = serialize($val);//Сериализуем значение
    $stmt = "SELECT `ID_user_session` FROM `session_variable` WHERE `ID_user_session` = '" . $this->ID_user_session . "' AND `variable_name` = '" . $nm . "'";
    if ($objDB->isRecordExist($stmt)) {
      $stmt = "UPDATE `session_variable` SET `variable_value` = '" . $strSer . "' WHERE `ID_user_session` = '" . $this->ID_user_session . "' AND `variable_name` = '" . $nm . "'";
    }
    else{
      //Вставляем значение в БД для текущей сессии, данного названия переменной $nm
      $stmt = "INSERT INTO `session_variable` (`ID_user_session`,`variable_name`,`variable_value`) VALUES (" . $this->ID_user_session . ",'" . $nm . "','" . $strSer . "')";
    }
    $objDB->query($stmt);
  }

  /**
   * Удаление значения параметра из сессии
   *
   * @param string $nm - Имя параметра
   */
  public function __delete($nm) {
    $objDB = Service_Database::instance();
    $stmt = "DELETE FROM `session_variable` WHERE ID_user_session = " . $this->ID_user_session . " AND variable_name='" . $nm . "'";
    $objDB->query($stmt);
  }

  /**
   * Функция берет переменую из сессии по имени
   *
   * @param string $nm - Имя параметра
   * @return string - Значение параметра
   */
  public function __get($nm) {
    $objDB = Service_Database::instance();
    //Получаем значение переменной $nm, относящееся к текущей сессии
    $arResult = $objDB->select("SELECT variable_value FROM `session_variable` WHERE ID_user_session = " . $this->ID_user_session . " AND variable_name = '" . $nm . "'");
    if (sizeof($arResult)>0) { // Если  есть элементы
      return(unserialize($arResult[sizeof($arResult)-1]["variable_value"]));//возвращаем значение
    }
    else { // Если нет элементов
      return false;
    }
  }

  /**
     * Функция записи массива значений массива переменных, относящихся к текущей сессии
     *
     * @param array $name - массив переменных
     */
    public function __setArray($name) {
      	$objDB = Service_Database::instance();
      	foreach ($name as $key => $value) {
      		$strSer = serialize($value); # Сериализуем значение
      		$stmt = "INSERT INTO `session_variable` (`ID_user_session`,`variable_name`,`variable_value`) VALUES (" . $this->ID_user_session . ",'" . $key . "','" . $strSer . "')";
      		$objDB->query($stmt);

      	}
     }

 	 /**
 	  * Получение массва значений переменных
 	  *
 	  * @return false/массив значений переменных
 	  */
     public function __getArray() {
      $objDB = Service_Database::instance();
      $arr = $objDB->select("SELECT variable_value, variable_name FROM `session_variable` WHERE ID_user_session = " . $this->ID_user_session);
      $arResult = array();
      for($i = 0; $i < sizeof($arr); $i++) {
	      $arResult[$arr[$i]['variable_name']] = $arr[$i]['variable_value'];

	      if (sizeof($arResult[$arr[$i]['variable_name']])>0) # Если  есть элементы
	        $arResult[$arr[$i]['variable_name']] = unserialize($arr[$i]["variable_value"]); # возвращаем значение # [sizeof($arResult)]
      }
      if (isset($arResult) && sizeof($arResult)>0)
      	return $arResult;
      else # Если нет элементов
        return(false);
 	}

 	/**
 	 * Функция удаления записей значений массива переменных
 	 *
 	 */
 	public function __deleteStr() {
 		$objDB = Service_Database::instance();
 		$func_list = func_get_args();
 		for($i = 0; $i < sizeof($func_list); $i++)
		{
			$stmt = 'DELETE FROM `session_variable`
    		WHERE `variable_name` = "' . $func_list[$i] . '"';
			$objDB->query($stmt);
		}
	}
 /**
  * Уничтожает лишние сессии
  *
  */
	public static function deleteBadSessions() {
		self::_deleteBadVariables();
		$objDB = Service_Database::instance();
		$stmt = "DELETE FROM `session`
    				WHERE `last_impression` < DATE_SUB(now(), INTERVAL 15 MINUTE)";
		$objDB->query($stmt);
	}

	/**
	 * Удаляет ишние переменные сессий
	 *
	 */
	public static function _deleteBadVariables() {
		$objDB = Service_Database::instance();
		$stmt = "SELECT `ID_session_variable` FROM `session_variable`
						LEFT JOIN `session` ON `session`.`ID_user_session` = `session_variable`.`ID_user_session`
    				WHERE `session`.`last_impression` < DATE_SUB(now(), INTERVAL 14 MINUTE) OR `session`.`last_impression` IS NULL";
		$arrIds = $objDB->selectSimpleArray($stmt);
		if (!$arrIds) return false;
		$stmt = "DELETE FROM `session_variable`
    				WHERE `ID_session_variable` IN(" . implode(',', $arrIds) . ")";
		$objDB->query($stmt);
		return true;
	}

	public function loginByOpenId($openId) {
    $objDB = Service_Database::instance();//Получаем подключение к БД
    $stmt = "SELECT `ID_user`, `login`, `pass` FROM `user` WHERE `open_id` = '" . $openId . "'";  //формируем SQL-запрос
    $arrUser = $objDB->select($stmt);
    if (sizeof($arrUser) > 0) {
    	$objSession = User_Session::instance();
			$ID_user = User_User::logIn($arrUser[0]['login'], $arrUser[0]['pass']);
			if ($ID_user) {//Если есть совпадения (логин+пароль)
				$this->ID_user = $ID_user;//Запоминаем id пользователя
				$this->logged_in = true;//Активируем сеанс
				//Обновляем БД
				//Устанавливаем статус активного сеанса, запоминаем id пользователя для текущ0его сеанса
				$this->_baseLogInSession();
				User_User::setLoginTime();
				User_User::addVisit();
				User_User::setStatus(2, $this->getUserId());
				$this->moveTo(W_ABSPATH);
			}
			else { // Если НЕТ совпадений (логин+пароль)
				return false;
			}
    }
	}

	/**
	 * Вход или регистрация по данным полученным с Facebook
	 *
	 */
	public function getFBCookieIfSet() {
		$cookie = Service_Function::getFacebookCookie(FB_APP_ID, FB_APP_SECRET);
		if (!empty($cookie['access_token'])) {
			$arrUser = json_decode(@file_get_contents('https://graph.facebook.com/me?access_token=' . $cookie['access_token']));
			if ($arrUser->id) {
				if (!$this->facebookLogin($arrUser->email)) {
					$objDB = Service_Database::instance();
					if (!empty($arrUser->link) && !User_User::isLoginExist(str_replace('http://www.facebook.com/', '', $arrUser->link)) && !preg_match('/=/', $arrUser->link)) {
					  $login = str_replace('http://www.facebook.com/', '', $arrUser->link);
					}
					elseif (!User_User::isLoginExist(str_replace(' ', '', $arrUser->name))) {
						$login = str_replace(' ', '', $arrUser->name);
					}
					else $login = $arrUser->id;
					$stmt = "INSERT INTO user (e_mail, login, first_name, last_name, pass, approved) VALUES ('" . $arrUser->email . "', '" . $login . "', '" . $arrUser->first_name . "', '" . $arrUser->last_name . "', '123456', 1)";
					$objDB->query($stmt);
					$ID_user = User_User::login($arrUser->email, '123456');
					if ($ID_user) {//Если есть совпадения (логин+пароль)
						$this->ID_user = $ID_user;//Запоминаем id пользователя
						$this->logged_in = true;//Активируем сеанс
						//Обновляем БД
						//Устанавливаем статус активного сеанса, запоминаем id пользователя для текущ0его сеанса
						$this->_baseLogInSession();
						User_User::setLoginTime();
						User_User::addVisit();
						User_User::setStatus(2, $this->getUserId());
					}
					if (empty($_SERVER['HTTP_REFERER'])) $this->moveTo(W_ABSPATH);
					else $this->moveTo(str_replace('fblogin=1', '', $_SERVER['HTTP_REFERER']));
				}
				$objUser = User_User::getUser();
				if ($objUser->getField('is_guide'))	$this->moveTo(W_ABSPATH . 'guide_news/');
				else {
					if (empty($_SERVER['HTTP_REFERER'])) {
						$this->moveTo(W_ABSPATH);
					}
					else $this->moveTo(str_replace('fblogin=1', '', $_SERVER['HTTP_REFERER']));
				}
			}
		}
	}
}
?>